package com.sichem.infrastructure.persistent.repository;

import com.sichem.domain.tag.adapter.repository.ITagRepository;
import com.sichem.domain.tag.model.entity.CrowdTagsJobEntity;
import com.sichem.infrastructure.persistent.dao.CrowdTagsDao;
import com.sichem.infrastructure.persistent.dao.CrowdTagsDetailDao;
import com.sichem.infrastructure.persistent.dao.CrowdTagsJobDao;
import com.sichem.infrastructure.persistent.po.CrowdTags;
import com.sichem.infrastructure.persistent.po.CrowdTagsDetail;
import com.sichem.infrastructure.persistent.po.CrowdTagsJob;
import com.sichem.infrastructure.redis.IRedisService;
import org.redisson.api.RBitSet;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.util.DuplicateFormatFlagsException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author xiangshizhen
 * @Date 2025/2/13
 */

@Repository
public class TagRepository implements ITagRepository {

    @Resource
    private CrowdTagsDao crowdTagsDao;

    @Resource
    private CrowdTagsDetailDao crowdTagsDetailDao;

    @Resource
    private CrowdTagsJobDao crowdTagsJobDao;

    @Resource
    private IRedisService redisService;

    @Override
    public CrowdTagsJobEntity queryCrowdTagsJobEntity(String tagId, String batchId) {

        CrowdTagsJob crowdTagsJobReq = new CrowdTagsJob();
        crowdTagsJobReq.setTagId(tagId);
        crowdTagsJobReq.setBatchId(batchId);

        CrowdTagsJob crowdTagsJobRes = crowdTagsJobDao.queryCrowdTagsJob(crowdTagsJobReq);

        return CrowdTagsJobEntity.builder()
                .tagType(crowdTagsJobRes.getTagType())
                .tagRule(crowdTagsJobReq.getTagRule())
                .statStartTime(crowdTagsJobReq.getStatStartTime())
                .statEndTime(crowdTagsJobReq.getStatEndTime())
                .build();

    }

    @Override
    public void addCrowdTagsUserId(String tagId, String userId) {

        CrowdTagsDetail crowdTagsDetailReq = new CrowdTagsDetail();
        crowdTagsDetailReq.setTagId(tagId);
        crowdTagsDetailReq.setUserId(userId);

        try {
            crowdTagsDetailDao.addCrowdTagsUserId(crowdTagsDetailReq);
            // 获取bitmap
            RBitSet bitSet = redisService.getBitSet(tagId);
            bitSet.set(redisService.getIndexFromUserId(userId));
        }catch (DuplicateKeyException ignore){

        }

    }

    @Override
    public void updateCrowdTagsStatistics(String tagId, int size) {

        CrowdTags crowdTagsReq = new CrowdTags();
        crowdTagsReq.setTagId(tagId);
        crowdTagsReq.setStatistics(size);

        crowdTagsDao.updateCrowdTagsStatistics(crowdTagsReq);

    }

    @Override
    public void loadTagsDetailToRedis() {
        List<CrowdTagsDetail> crowdTagsDetails = crowdTagsDetailDao.queryAll();
        // 转换为以 tagId 为键，包含此 tagId 的 CrowdTagsDetail 列表为值的 Map
        // 过滤掉 tagId 为 null 的元素，再进行分组
        Map<String, List<CrowdTagsDetail>> tagIdMap = crowdTagsDetails.stream()
                .filter(detail -> detail.getTagId() != null)
                .collect(Collectors.groupingBy(CrowdTagsDetail::getTagId));
        for (Map.Entry<String, List<CrowdTagsDetail>> entry : tagIdMap.entrySet()) {
            System.out.println("TagId: " + entry.getKey());
            for (CrowdTagsDetail detail : entry.getValue()) {
                System.out.println("  UserId: " + detail.getUserId());
            }
        }

        for (Map.Entry<String, List<CrowdTagsDetail>> entry : tagIdMap.entrySet()) {

            String key = entry.getKey();
            RBitSet bitSet = redisService.getBitSet(key);

            List<CrowdTagsDetail> value = entry.getValue();
            value.forEach(crowdTagsDetail -> {
                int indexFromUserId = redisService.getIndexFromUserId(crowdTagsDetail.getUserId());
                bitSet.set(indexFromUserId);
            });
        }

    }
}
